package cn.jaye.fabric.application;

import cn.jaye.fabric.application.command.DeployChainCodeCommand;
import cn.jaye.fabric.application.command.ExecuteChaincodeCommand;
import cn.jaye.fabric.application.command.InfoChainCodeCommand;
import cn.jaye.fabric.common.constant.Global;
import cn.jaye.fabric.domain.service.RestTemplateService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author Jaye
 * @create 2018-05-25 14:12
 */
@Service
public class ChainCodeApplicationService {


    @Autowired
    private RestTemplateService restTemplateService;


    private static final String CHAINCODE_LIST = "/mchaincode/list";

    private static final String CHAINCODE_INFO = "/mchaincode/info";
    private static final String CHAINCODE_INVOKE = "/chaincode/invoke";
    private static final String CHAINCODE_QUERY = "/chaincode/query";
    private static final String CHAINCODE_INSTALL = "/chaincode/install";
    private static final String CHAINCODE_INSTANTIATE = "/chaincode/instantiate";

    public JSONArray list() {
        String url = Global.FABRRIC_GATEWAY_ADDRESS + CHAINCODE_LIST;
        JSONObject postData = new JSONObject();
        JSONObject resultObject = restTemplateService.getUrlResponse(url, postData);
        return resultObject.getJSONArray("data");
    }

    public JSONObject info(InfoChainCodeCommand infoChainCodeCommand) {
        String url = Global.FABRRIC_GATEWAY_ADDRESS + CHAINCODE_INFO;
        JSONObject postData = new JSONObject();
        postData.put("chaincodeId", infoChainCodeCommand.getChaincodeId());
        JSONObject resultObject = restTemplateService.getUrlResponse(url, postData);
        return resultObject;
    }

    public JSONObject execute(ExecuteChaincodeCommand executeChaincodeCommand) {
        String url = Global.FABRRIC_GATEWAY_ADDRESS;
        if ("query".equals(executeChaincodeCommand.getReqType())) {
            url += CHAINCODE_QUERY;
        } else {
            url += CHAINCODE_INVOKE;
        }
        String data = executeChaincodeCommand.getData();
        JSONObject postData = JSON.parseObject(data);
        JSONObject resultObject = restTemplateService.getUrlResponse(url, postData);
        return resultObject;
    }

    public JSONObject install(DeployChainCodeCommand deployChainCodeCommand) {
        String url = Global.FABRRIC_GATEWAY_ADDRESS + CHAINCODE_INSTALL;
        JSONObject resultObject = restTemplateService.getUrlResponse(url, convert(deployChainCodeCommand));
        return resultObject;
    }

    public JSONObject instantiate(DeployChainCodeCommand deployChainCodeCommand) {
        String url = Global.FABRRIC_GATEWAY_ADDRESS + CHAINCODE_INSTANTIATE;
        JSONObject resultObject = restTemplateService.getUrlResponse(url, convert(deployChainCodeCommand));
        return resultObject;
    }

    private JSONObject convert(DeployChainCodeCommand deployChainCodeCommand) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("peerIds", deployChainCodeCommand.getPeerIds());
        JSONObject channel = new JSONObject();
        channel.put("name", deployChainCodeCommand.getChannelName());
        JSONObject chainCode = new JSONObject();
        chainCode.put("name", deployChainCodeCommand.getChaincodeName());
        chainCode.put("version", deployChainCodeCommand.getChaincodeVersion());
        chainCode.put("path", deployChainCodeCommand.getChaincodePath());
        chainCode.put("location", deployChainCodeCommand.getChaincodeLocation());
        chainCode.put("args", deployChainCodeCommand.getArgs());
        jsonObject.put("channel", channel);
        jsonObject.put("chainCode", chainCode);
        return jsonObject;
    }
}